package ewa.memory.api;

import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import static ewa.memory.api.Manager.State.*;

public class ManagerTest {
	private Manager manager;
	
	@Before
	public void setUp() {
		manager = new Manager();
		manager.init(Manager.getDefaultCards(), 4, 4);
	}
	
	@Test
	public void getRows_shouldReturn4() {
		assertEquals(4, manager.getRows());
	}
	
	@Test
	public void getCols_shouldReturn4() {
		assertEquals(4, manager.getCols());
	}
	
	@Test
	public void isShown_shouldReturnFalse() {
		for (int i = 0; i < manager.getRows(); i++) {
			for (int j = 0; j < manager.getCols(); j++) {
				assertFalse(manager.isShown(i,j));
			}
		}
	}
	
	@Test
	public void unconver_oneUncovered() {
		manager.uncover(0, 0);
		assertEquals(ONE_UNCOVERED, manager.getState());
		assertEquals(manager.getCard(0,0), manager.getFirstUncovered());
		assertNull(manager.getSecondUncovered());
	}
	
	public int[] getOtherCard(int i, int j) {
		return getOtherCard(manager.getCard(i, j));
	}
	
	public int[] getOtherCard(Card c) {
		for (int i = 0; i < manager.getRows(); i++) {
			for (int j = 0; j < manager.getCols(); j++) {
				if (c.equals(manager.getCard(i, j))
						&& c != manager.getCard(i, j)) {
					return new int[] { i, j };
				}
			}
		}
		return null;
	}
		
	@Test
	public void uncover_match() {
		int[] other = getOtherCard(0, 0);
		
		manager.uncover(0, 0);
		manager.uncover(other[0], other[1]);
		
		assertEquals(START, manager.getState());
		assertNull(manager.getFirstUncovered());
		assertNull(manager.getSecondUncovered());
	}
	
	@Test
	public void uncover_mismatch() {
		int[] other = getOtherCard(0, 0);
		other[1] = (other[1]+1) % manager.getCols();
		
		manager.uncover(0, 0);
		manager.uncover(other[0], other[1]);
		
		assertEquals(MISMATCH, manager.getState());
		assertEquals(manager.getCard(0,0), manager.getFirstUncovered());
		assertEquals(manager.getCard(other[0], other[1]), manager.getSecondUncovered());
		
		manager.uncover(0, 0);
		assertEquals(ONE_UNCOVERED, manager.getState());
		assertTrue(manager.getCard(0,0).isShown());
		assertFalse(manager.getCard(other[0], other[1]).isShown());
	}
	
	@Test
	public void uncover_twice() {
		manager.uncover(0, 0);
		manager.uncover(0, 0);
		
		assertEquals(MISMATCH, manager.getState());
	}

}
